using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace HEFramework
{
    /// <summary>
    ///
    /// AB资源设置数据体编辑器
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-12-21 17:13:54
    /// ----------------------------------------
    /// </summary>
    public class AssetBundleSettingScriptableObjectEditor : EditorWindow
    {
        private const int NAME_LENGTH = 120;
        private const int VALUE_LENGTH = 350;
        private const int NAME_HEIGHT = 18;
        private const int HELP_LENGTH = 475;


        private AssetBundleSettingScriptableObject data;
        private GUILayoutOption[] nameOptions;
        private GUILayoutOption[] valueOptions;


        private BuildAssetBundleOptions options;
        private BuildTarget target;

        /// <summary>
        /// 打开编辑面板时初始化
        /// </summary>
        private void Awake()
        {
            data = AssetBundleSettingScriptableObject.Instance;
            nameOptions = new[] { GUILayout.Width(NAME_LENGTH), GUILayout.Height(NAME_HEIGHT) };
            valueOptions = new[] { GUILayout.Width(VALUE_LENGTH), GUILayout.Height(NAME_HEIGHT) };
            options = BuildAssetBundleOptions.None;
            target = BuildTarget.Android;
        }


        public static void OpenSettingsWindow()
        {
            try
            {
                if (EditorApplication.isCompiling)
                {
                    return;
                }

                var window = GetWindowWithRect<AssetBundleSettingScriptableObjectEditor>(new Rect(0, 0, 520, 710), true, "AssetBundle Setting", true);
                window.Show();
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
            }
        }


        private void OnGUI()
        {
            AssetBundleGUIStyle.Ensure();


            if (data == null)
            {
                Debug.LogError("Setting data is none.");
            }


            GUILayout.BeginHorizontal();
            GUILayout.Space(5);
            GUILayout.Label("AssetBundle设置", AssetBundleGUIStyle.LargeLabel);
            GUILayout.Space(5);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Space(30);
            GUILayout.Space(30);
            if (GUILayout.Button("重置全部", GUILayout.Width(100), GUILayout.Height(20)))
            {
                if (EditorUtility.DisplayDialog("AssetBundleTool", "Are you sure to reset all settings?", "Yes", "Cancel"))
                {
                    //清理之前的Ab路径
                    AssetBundleBuildEditor.ClearAssetBundlePath();
                    //数据重置
                    AssetBundleSettingScriptableObject.Instance.ResetAll();
                    EditorUtility.SetDirty(AssetBundleSettingScriptableObject.Instance);
                }
            }

            GUILayout.Space(10);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("AssetBundle数据目录路径", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("目录路径", AssetBundleGUIStyle.Label, nameOptions);
            data.AssetBundleDataOriginalPath = EditorGUILayout.TextField(data.AssetBundleDataOriginalPath, AssetBundleGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("AssetBundle数据输出路径", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("输出路径", AssetBundleGUIStyle.Label, nameOptions);
            data.AssetBundleDataBuildTargetPath = EditorGUILayout.TextField(data.AssetBundleDataBuildTargetPath, AssetBundleGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("当前环境", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("环境", AssetBundleGUIStyle.Label, nameOptions);
            data.Domain = (eDomain)EditorGUILayout.EnumPopup("", data.Domain, valueOptions);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("AssetBundle环境目录", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("目录", AssetBundleGUIStyle.Label, nameOptions);
            data.AssetBundleDataDomainFolder = EditorGUILayout.TextField(data.AssetBundleDataDomainFolder, AssetBundleGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();


            if (data.Domain == eDomain.Persistent)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("AssetBundle数据下载URL", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
                GUILayout.Label("URL", AssetBundleGUIStyle.Label, nameOptions);
                data.AssetBundleDataDownloadURL = EditorGUILayout.TextField(data.AssetBundleDataDownloadURL, AssetBundleGUIStyle.TextField, valueOptions);
                GUILayout.EndHorizontal();
            }

            GUILayout.BeginHorizontal();
            GUILayout.Label("AssetBundle是否加密", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("是否加密", AssetBundleGUIStyle.Label, nameOptions);
            data.Encrypt = GUILayout.Toggle(data.Encrypt, "");
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("AssetBundle加密Key", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("Key", AssetBundleGUIStyle.Label, nameOptions);
            data.Key = EditorGUILayout.TextField(data.Key, AssetBundleGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("AssetBundle加密IV", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("IV", AssetBundleGUIStyle.Label, nameOptions);
            data.IV = EditorGUILayout.TextField(data.IV, AssetBundleGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("AssetBundle加密模式", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("加密模式", AssetBundleGUIStyle.Label, nameOptions);
            data.Compress = (BuildAssetBundleOptions)EditorGUILayout.EnumPopup("", data.Compress, valueOptions);
            GUILayout.EndHorizontal();


            DrawLine();
            DrawLine();
            DrawLine();


            GUILayout.BeginHorizontal();
            GUILayout.Label("选择平台", AssetBundleGUIStyle.Label, nameOptions);
            target = (BuildTarget)EditorGUILayout.EnumPopup("", target, valueOptions);
            GUILayout.EndHorizontal();


            if (GUILayout.Button("打包"))
            {
                AssetBundleBuildEditor.AssetBundlesBuild(target);
            }

            GUILayout.BeginHorizontal();
            GUILayout.Label("将生成的AB文件复制到环境目录下[Streaming][Persistent]", AssetBundleGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("复制"))
            {
                if (data.Domain != eDomain.Streaming && data.Domain != eDomain.Persistent)
                {
                    Debug.LogError("Domain error!");
                    return;
                }

                string s = data.AssetBundleDataBuildTargetPath + "/" + target;
                string t = data.GetAssetBundleDataLoadPath();
                DirectoryCopy(s, t, true);
                //打开窗口
                UnityEditor.EditorUtility.RevealInFinder(t);
            }

            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            if (GUILayout.Button("清除"))
            {
                if (data.Domain != eDomain.Streaming && data.Domain != eDomain.Persistent)
                {
                    Debug.LogError("Domain error!");
                    return;
                }

                string t = data.GetAssetBundleDataLoadPath();
                DirectoryDelete(t);
            }

            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            if (GUILayout.Button("清除AB标识"))
            {
                AssetBundleBuildEditor.ClearAssetBundlePath();
            }

            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("说明", AssetBundleGUIStyle.BoldLabel, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            string cnStr =
                "Unity模式：读取AssetBundles目录下的文件。\n" +
                "Resources模式：读取Resources目录下的文件。\n" +
                "Persistent模式：读取Application.persistentDataPath目录下的AB文件。\n" +
                "Streaming模式：读取Application.streamingAssetsPath目录下的AB文件。\n";
            GUILayout.Label(cnStr, AssetBundleGUIStyle.TextArea, GUILayout.Width(HELP_LENGTH), GUILayout.Height(58));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("注意事项", AssetBundleGUIStyle.BoldLabel, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            cnStr =
                "AssetBundles目录的规则为存在文件的目录下不能有子目录，否则会导致打包失败！\n" +
                "Persistent模式下需将打包的AssetBundles目录放到数据下载URL的目录下。\n";
            GUILayout.Label(cnStr, AssetBundleGUIStyle.TextArea, GUILayout.Width(HELP_LENGTH), GUILayout.Height(30));
            GUILayout.EndHorizontal();
        }


        /// <summary>
        /// 给界面划横线
        /// </summary>
        private void DrawLine()
        {
            GUILayout.Box("", GUILayout.Height(2F), GUILayout.ExpandWidth(true));
        }


        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="_o"></param>
        /// <param name="_t"></param>
        /// <param name="_sub"></param>
        /// <exception cref="DirectoryNotFoundException"></exception>
        private void DirectoryCopy(string _o, string _t, bool _sub)
        {
            // 获取源文件夹的目录信息
            System.IO.DirectoryInfo source = new System.IO.DirectoryInfo(_o);
            // 如果源目录不存在，则抛出异常
            if (!source.Exists)
            {
                throw new System.IO.DirectoryNotFoundException("Source directory does not exist or could not be found: " + _o);
            }

            // 获取源文件夹中的文件和子目录
            System.IO.FileInfo[] files = source.GetFiles();
            System.IO.DirectoryInfo[] dirs = source.GetDirectories();

            // 如果目标目录不存在，则创建它
            if (!System.IO.Directory.Exists(_t))
            {
                System.IO.Directory.CreateDirectory(_t);
            }

            // 复制所有文件到新位置
            foreach (System.IO.FileInfo file in files)
            {
                string temp = System.IO.Path.Combine(_t, file.Name);
                file.CopyTo(temp, true); // 如果目标文件已存在，覆盖
            }

            // 如果复制子目录且子目录存在，则递归复制它们
            if (_sub)
            {
                foreach (System.IO.DirectoryInfo child in dirs)
                {
                    string temp = System.IO.Path.Combine(_t, child.Name);
                    DirectoryCopy(child.FullName, temp, _sub);
                }
            }
#if UNITY_EDITOR
            UnityEditor.AssetDatabase.Refresh();
#endif
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="_path"></param>
        /// <returns></returns>
        public bool DirectoryDelete(string _path)
        {
            try
            {
                // 确保目录存在
                if (System.IO.Directory.Exists(_path))
                {
                    // 删除目录中的所有文件
                    string[] files = System.IO.Directory.GetFiles(_path);
                    foreach (string file in files)
                    {
                        System.IO.File.SetAttributes(file, System.IO.FileAttributes.Normal); // 将文件属性设置为正常，确保文件不是只读
                        System.IO.File.Delete(file);
                    }

                    // 递归删除所有子目录
                    string[] subDirs = System.IO.Directory.GetDirectories(_path);
                    foreach (string subDir in subDirs)
                    {
                        DirectoryDelete(subDir);
                    }

                    // 删除现在空的目录
                    System.IO.Directory.Delete(_path, true);
                }
            }
            catch (Exception e)
            {
                return false;
            }
#if UNITY_EDITOR
            UnityEditor.AssetDatabase.Refresh();
#endif

            System.IO.File.Delete(_path + ".meta");

#if UNITY_EDITOR
            UnityEditor.AssetDatabase.Refresh();
#endif

            return true;
        }
    }
}